﻿Public Class B1Tree
    Implements IB1Tree
    Private WithEvents myB1Form As B1Form
    Public Event B1TreeEvent(ByVal pVal As IB1TreeEvent, ByRef BubbleEvent As Boolean) Implements IB1Tree.B1TreeEvent

    Private _TreeUID As String
    Private _Pic_COLLAPSE As String = "COLLAPSE"
    Private _Pic_COLLAPSE_OPEN As String = "COLLAPSE_OPEN"
    Private _Pic_NoChilds As String = ""
    Private _Col_Key As String = "col_key"
    Private _Col_Icon As String = "col_icon"
    Private _Col_Show As String = "col_show"
    Private _Col_Father As String = "col_father"
    Private _Col_Level As String = "col_level"
    Private _Col_Type As String = "col_type"
    Private _Col_TypeShow As String = "col_tpshow"
    Private _Col_Descrp As String = "col_descrp"
    Private _Col_f As String = "col_f"
    Private _LevelChar As String = "　"
    Private _TreeSelectedRow As Integer = 0

    Private ReadOnly Property myCurrentForm As SAPbouiCOM.Form
        Get
            Return myB1Form.CurrentForm
        End Get
    End Property

    ''' <summary>
    ''' 构造函数
    ''' </summary>
    ''' <param name="B1Form"></param>
    ''' <param name="TreeUID"></param>
    ''' <remarks></remarks>
    Sub New(ByVal B1Form As B1Form, ByVal TreeUID As String)
        myB1Form = B1Form
        _TreeUID = TreeUID
    End Sub

#Region "Property"


    ''' <summary>
    ''' 控件UID
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property TreeUID As String
        Get
            Return _TreeUID
        End Get
    End Property

    ''' <summary>
    ''' #
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_First As String
        Get
            Return _Col_f
        End Get
    End Property

    Public ReadOnly Property udsCol_First As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_First)
        End Get
    End Property

    ''' <summary>
    ''' 描述
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Descrp As String
        Get
            Return _Col_Descrp
        End Get
    End Property

    Public ReadOnly Property udsCol_Descrp As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Descrp)
        End Get
    End Property

    ''' <summary>
    ''' 行类型
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_TypeShow As String
        Get
            Return _Col_TypeShow
        End Get
    End Property

    Public ReadOnly Property udsCol_TypeShow As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_TypeShow)
        End Get
    End Property

    ''' <summary>
    ''' 行类型
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Type As String
        Get
            Return _Col_Type
        End Get
    End Property

    Public ReadOnly Property udsCol_Type As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Type)
        End Get
    End Property

    ''' <summary>
    ''' 控件列：行关键值
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Key As String
        Get
            Return _Col_Key
        End Get
    End Property

    Public ReadOnly Property udsCol_Key As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Key)
        End Get
    End Property

    ''' <summary>
    ''' 控件列：行展开、收缩图标
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Icon As String
        Get
            Return _Col_Icon
        End Get
    End Property

    Public ReadOnly Property udsCol_Icon As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Icon)
        End Get
    End Property

    ''' <summary>
    ''' 控件列：行显示
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Show As String
        Get
            Return _Col_Show
        End Get
    End Property

    Public ReadOnly Property udsCol_Show As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Show)
        End Get
    End Property

    ''' <summary>
    ''' 控件列：行父项
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Father As String
        Get
            Return _Col_Father
        End Get
    End Property

    Public ReadOnly Property udsCol_Father As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Father)
        End Get
    End Property

    ''' <summary>
    ''' 控件列：行当前层数
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Col_Level As String
        Get
            Return _Col_Level
        End Get
    End Property '

    Public ReadOnly Property udsCol_Level As SAPbouiCOM.UserDataSource
        Get
            Return Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Col_Level)
        End Get
    End Property

#End Region

    Private Function CreateTreeEvent() As B1TreeEvent
        Dim TreeEvent As B1TreeEvent = New B1TreeEvent
        With TreeEvent
            ._ItemUID = TreeUID
            ._FormUID = myCurrentForm.UniqueID
            ._FormType = myCurrentForm.TypeEx
        End With
        Return TreeEvent
    End Function

    Public ReadOnly Property TreeItem As SAPbouiCOM.Matrix
        Get
            Return myCurrentForm.Items.Item(Me.TreeUID).Specific
        End Get
    End Property

    Private Sub B1Form_frm_ItemEvent(ByVal pVal As B1AddonBase.B1ItemEvent, ByRef BubbleEvent As Boolean) Handles myB1Form.frm_ItemEvent
        Dim TreeEvent As B1TreeEvent
        Dim RowStatus As RowStatus
        Dim TreeBubbleEvent As Boolean
        Try
            If pVal.ItemUID = TreeUID Then
                If pVal.BeforeAction Then
                    If pVal.Row = 0 Then BubbleEvent = False : Exit Sub
                    If pVal.Row > 0 And pVal.Row <= Me.TreeItem.RowCount Then
                        If pVal.EventType = SAPbouiCOM.BoEventTypes.et_CLICK Or pVal.EventType = SAPbouiCOM.BoEventTypes.et_ITEM_PRESSED Then
                            TreeEvent = CreateTreeEvent()
                            TreeEvent._ActionSuccess = False
                            TreeEvent._BeforeAction = True
                            TreeEvent._ColUID = pVal.ColUID
                            TreeEvent._Row = pVal.Row
                            TreeEvent._EventType = TreeEventType.et_NodeClick
                            RaiseEvent B1TreeEvent(TreeEvent, BubbleEvent)
                        End If
                    End If
                Else
                    If pVal.Row > 0 And pVal.Row <= Me.TreeItem.RowCount Then
                        If pVal.EventType = SAPbouiCOM.BoEventTypes.et_CLICK Then
                            TreeEvent = CreateTreeEvent()
                            TreeEvent._ActionSuccess = True
                            TreeEvent._BeforeAction = False
                            TreeEvent._ColUID = pVal.ColUID
                            TreeEvent._Row = pVal.Row
                            TreeEvent._EventType = TreeEventType.et_NodeClick
                            TreeEvent._NodeKeyValue = getRowValue(Me.Col_Key, pVal.Row)
                            TreeItem.GetLineData(pVal.Row)
                            RaiseEvent B1TreeEvent(TreeEvent, False)
                            TreeEvent = Nothing
                            '节点点击（展开或收缩）
                            If pVal.ColUID = Me.Col_Icon Then
                                RowStatus = getRowStatus(pVal.ColUID, pVal.Row)
                                If RowStatus = RowStatus.rs_COLLAPSE Then '节点由收缩变为展开
                                    TreeEvent = CreateTreeEvent()
                                    TreeEvent._ActionSuccess = True
                                    TreeEvent._BeforeAction = False
                                    TreeEvent._ColUID = pVal.ColUID
                                    TreeEvent._Row = pVal.Row
                                    TreeEvent._EventType = TreeEventType.et_ExpandLine
                                    TreeEvent._NodeKeyValue = getRowValue(Me.Col_Key, pVal.Row)
                                    TreeBubbleEvent = False
                                    RaiseEvent B1TreeEvent(TreeEvent, TreeBubbleEvent)

                                ElseIf RowStatus = SAPBoAddon.RowStatus.rs_COLLAPSE_OPEN Then '节点由展开变为收缩
                                    TreeEvent = CreateTreeEvent()
                                    TreeEvent._ActionSuccess = False
                                    TreeEvent._BeforeAction = True
                                    TreeEvent._ColUID = pVal.ColUID
                                    TreeEvent._Row = pVal.Row
                                    TreeEvent._EventType = TreeEventType.et_CollspseLine
                                    TreeEvent._NodeKeyValue = getRowValue(Me.Col_Key, pVal.Row)
                                    TreeBubbleEvent = True
                                    RaiseEvent B1TreeEvent(TreeEvent, TreeBubbleEvent)
                                    If TreeBubbleEvent Then
                                        Me.CollspseLine(pVal.Row)
                                        TreeEvent._ActionSuccess = True
                                        TreeEvent._BeforeAction = False

                                        RaiseEvent B1TreeEvent(TreeEvent, TreeBubbleEvent)
                                    End If
                                End If
                                '【更换行状态 图标】wp添加
                                'Me.SetIconValue(pVal.Row, myCurrentForm.DataSources.UserDataSources.Item(Col_Icon))
                            Else

                            End If
                        End If
                        If pVal.EventType = SAPbouiCOM.BoEventTypes.et_ITEM_PRESSED And pVal.ColUID = Me.Col_First Then
                            TreeEvent = CreateTreeEvent()
                            TreeEvent._ActionSuccess = True
                            TreeEvent._BeforeAction = False
                            TreeEvent._ColUID = pVal.ColUID
                            TreeEvent._Row = pVal.Row
                            TreeEvent._EventType = TreeEventType.et_RowSelected
                            TreeEvent._NodeKeyValue = getRowValue(Me.Col_Key, pVal.Row)
                            TreeBubbleEvent = True
                            RaiseEvent B1TreeEvent(TreeEvent, TreeBubbleEvent)
                        End If
                    End If
                End If
            End If
        Catch ex As Exception
            B1Addon.B1Addon.SBOAddOn.StatusBarMessage("不能识别的事件," & ex.Message & " by B1Tree.", SAPbouiCOM.BoStatusBarMessageType.smt_Error)
        End Try
    End Sub

    Private Sub B1Form_frm_MenuEvent(ByVal pVal As B1AddonBase.B1MenuEvent, ByRef BubbleEvent As Boolean) Handles myB1Form.frm_MenuEvent
        Dim TreeEvent As B1TreeEvent
        Try
            If pVal.ItemUID = TreeUID Then
                If pVal.BeforeAction Then

                Else
                    TreeEvent = CreateTreeEvent()
                    TreeEvent._ActionSuccess = True
                    TreeEvent._BeforeAction = False
                    TreeEvent._ColUID = pVal.ColUID
                    TreeEvent._Row = pVal.Row
                    TreeEvent._EventType = TreeEventType.et_MenuClick
                    TreeEvent._MenuUID = pVal.MenuUID
                    TreeEvent._NodeKeyValue = getRowValue(Me.Col_Key, pVal.Row)

                    RaiseEvent B1TreeEvent(TreeEvent, False)
                End If
            End If
        Catch ex As Exception
            B1Addon.B1Addon.SBOAddOn.StatusBarMessage("不能识别的事件," & ex.Message & " by B1Tree.", SAPbouiCOM.BoStatusBarMessageType.smt_Error)
        End Try
    End Sub

    Private Function CollspseLine(ByVal pVal As B1AddonBase.B1ItemEvent) As Boolean
        Dim mtx As SAPbouiCOM.Matrix = Me.TreeItem
        Dim KeyValue As String = SAPBoAddon.B1Assistant.Matrix.GetCellValue(mtx, Me.Col_Key, pVal.Row)
        Dim i As Integer = pVal.Row + 1
        Try
            Do Until i > mtx.RowCount
                If SAPBoAddon.B1Assistant.Matrix.GetCellValue(mtx, Me.Col_Father, i) = KeyValue Then
                    mtx.DeleteRow(i)
                    i -= 1
                Else
                    Exit Do
                End If
                i += 1
            Loop
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    ''' <summary>
    '''  递归折叠子项 - paradox
    ''' </summary>
    ''' <param name="startRow"></param>
    ''' <returns>删除行数</returns>
    ''' <remarks></remarks>
    Public Function CollspseLine(ByVal startRow As Integer) As Integer
        Dim mtx As SAPbouiCOM.Matrix
        Dim iCurrentRow As Integer
        Dim Count As Integer
        Dim FatherKey As String
        Dim strFitList As String
        Dim strKey As String
        Dim fatherrow As Integer
        Try
            fatherrow = startRow
            mtx = Me.TreeItem
            '初始化
            iCurrentRow = startRow + 1 '设置当前行为起始行的下一行
            Count = mtx.RowCount 'Matrix共有多少行
            strFitList = "'" & SAPBoAddon.B1Assistant.Matrix.GetCellValue(mtx, Col_Key, startRow).ToString.Trim & "';" '初始化匹配字符串
            '开始处理收缩树节点
            '循环处理Matrix内数据
            While startRow < Count
                FatherKey = SAPBoAddon.B1Assistant.Matrix.GetCellValue(mtx, Col_Father, iCurrentRow).ToString.Trim

                If strFitList.Contains("'" & FatherKey & "'") Then
                    strKey = SAPBoAddon.B1Assistant.Matrix.GetCellValue(mtx, Col_Key, iCurrentRow).ToString.Trim '获得被删除行的行号

                    If strFitList.Contains("'" & strKey & "'") = False Then
                        strFitList = strFitList & "'" & strKey & "';" '将行号拼接到匹配字符串里
                    End If

                    mtx.DeleteRow(iCurrentRow) '移除一行
                Else '如果不满足移除条件则跳到下一行
                    iCurrentRow = iCurrentRow + 1
                End If

                startRow = startRow + 1
            End While
            SetRowStatus(fatherrow, RowStatus.rs_COLLAPSE)
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Public Sub GetLineData(ByVal iRow As Integer)
        Me.TreeItem.GetLineData(iRow)
    End Sub

    Public Sub SetLineData(ByVal iRow As Integer)
        Me.TreeItem.SetLineData(iRow)
    End Sub

    Private Function getRowValue(ByVal Col As String, ByVal Row As Integer) As String
        Return SAPBoAddon.B1Assistant.Item.GetValue(myCurrentForm.UniqueID, Me.TreeUID, Col, Row)
    End Function

    ''' <summary>
    ''' 更换图片路径
    ''' </summary>
    ''' <param name="cRow"></param>
    ''' <param name="udsIcon"></param>
    ''' <remarks></remarks>
    Private Sub SetIconValue(ByVal cRow As Int32, ByVal udsIcon As SAPbouiCOM.UserDataSource)
        Dim omtx As SAPbouiCOM.Matrix
        Dim udsIconVal As String
        omtx = myCurrentForm.Items.Item("10").Specific
        omtx.GetLineData(cRow)
        udsIconVal = udsIcon.Value
        If udsIconVal = _Pic_COLLAPSE Then
            udsIcon.Value = Me._Pic_COLLAPSE_OPEN
        ElseIf udsIconVal = _Pic_COLLAPSE_OPEN Then
            udsIcon.Value = Me._Pic_COLLAPSE
        End If
        omtx.SetLineData(cRow)
    End Sub

    Public Sub SetRowColumnValue(ByVal colUID As String, ByVal Row As Integer, ByVal Value As String)
        Me.TreeItem.GetLineData(Row)
        Dim uds As SAPbouiCOM.UserDataSource = Me.myB1Form.CurrentForm.DataSources.UserDataSources.Item(Me.TreeItem.Columns.Item(colUID).DataBind.Alias)
        uds.ValueEx = Value
        Me.TreeItem.SetLineData(Row)
    End Sub

    Public Sub SetRowStatus(ByVal row As Integer, ByVal status As RowStatus)
        Select Case status
            Case RowStatus.rs_COLLAPSE
                SetRowColumnValue(Me._Col_Icon, row, Me._Pic_COLLAPSE)
            Case RowStatus.rs_COLLAPSE_OPEN
                SetRowColumnValue(Me._Col_Icon, row, Me._Pic_COLLAPSE_OPEN)
            Case RowStatus.rs_NA
                SetRowColumnValue(Me._Col_Icon, row, Me._Pic_NoChilds)
        End Select

    End Sub

    Private Function getRowStatus(ByVal Col As String, ByVal Row As Integer) As RowStatus

        Select Case getRowValue(Col, Row)
            Case Me._Pic_COLLAPSE
                Return RowStatus.rs_COLLAPSE
            Case Me._Pic_COLLAPSE_OPEN
                Return RowStatus.rs_COLLAPSE_OPEN
            Case Me._Pic_NoChilds
                Return RowStatus.rs_NA
            Case Else
                Return RowStatus.rs_NA
        End Select
    End Function

    Private Function get_LevelChar(ByVal Level As Integer) As String
        Dim tmpStr As String = ""
        For i As Integer = 1 To Level - 1
            tmpStr += _LevelChar
        Next
        Return tmpStr
    End Function

    ''' <summary>
    ''' 设置行值
    ''' -1 为新建行
    ''' </summary>
    ''' <param name="iRow">-1为新行</param>
    ''' <param name="Col_Type"></param>
    ''' <param name="Col_Key"></param>
    ''' <param name="Col_Descrp"></param>
    ''' <param name="Col_Level"></param>
    ''' <param name="Col_Father"></param>
    ''' <remarks></remarks>
    Public Sub SetRowValues(ByVal iRow As Integer, ByVal Col_Type As String, ByVal Col_TypeShow As String, ByVal Col_Key As String, ByVal Col_Descrp As String, ByVal Col_Level As Integer, ByVal Col_Father As String, ByVal RowStatus As RowStatus)
        If iRow <> -1 Then
            Me.TreeItem.GetLineData(iRow)
        End If
        udsCol_Key.ValueEx = Col_Key
        udsCol_Icon.ValueEx = getRowStatuePicture(RowStatus)
        udsCol_Father.ValueEx = Col_Father
        udsCol_Level.ValueEx = Col_Level
        udsCol_Show.ValueEx = get_LevelChar(Col_Level) & Col_Key
        udsCol_Descrp.ValueEx = Col_Descrp
        udsCol_Type.ValueEx = Col_Type
        udsCol_TypeShow.ValueEx = Col_TypeShow
        If iRow = -1 Then
            Me.TreeItem.AddRow()
        Else
            Me.TreeItem.SetLineData(iRow)
        End If
    End Sub

    Public Sub AddRowValues(ByVal fatherRow As Integer, ByVal Col_Type As String, ByVal Col_TypeShow As String, ByVal Col_Key As String, ByVal Col_Descrp As String, ByVal Col_Level As Integer, ByVal Col_Father As String, ByVal RowStatus As RowStatus)
        Me.TreeItem.GetLineData(fatherRow)
        udsCol_Key.ValueEx = Col_Key
        udsCol_Icon.ValueEx = getRowStatuePicture(RowStatus)
        udsCol_Father.ValueEx = Col_Father
        udsCol_Level.ValueEx = Col_Level
        udsCol_Show.ValueEx = get_LevelChar(Col_Level) & Col_Key
        udsCol_Descrp.ValueEx = Col_Descrp
        udsCol_Type.ValueEx = Col_Type
        udsCol_TypeShow.ValueEx = Col_TypeShow
        Me.TreeItem.AddRow(1, fatherRow)
    End Sub

    Public ReadOnly Property TreeSelectedRow As Integer
        Get
            For i As Integer = 1 To TreeItem.RowCount
                If TreeItem.IsRowSelected(i) Then
                    Return i
                End If
            Next
            Return 0
        End Get
    End Property

    Private Function getRowStatuePicture(ByVal rowStatus As RowStatus) As String
        Select Case rowStatus
            Case SAPBoAddon.RowStatus.rs_COLLAPSE_OPEN
                Return Me._Pic_COLLAPSE_OPEN
            Case SAPBoAddon.RowStatus.rs_COLLAPSE
                Return Me._Pic_COLLAPSE
            Case SAPBoAddon.RowStatus.rs_NA
                Return Me._Pic_NoChilds
        End Select
        Return Me._Pic_NoChilds
    End Function
End Class

Public Enum TreeEventType
    et_Initialize = 0
    et_NodeClick = 1
    et_CollspseLine = 2
    et_ExpandLine = 3
    et_MenuClick = 4
    et_RowSelected = 5
End Enum

Public Enum RowStatus
    rs_NA = 0
    rs_COLLAPSE = 1
    rs_COLLAPSE_OPEN = 2
End Enum